<script setup lang="ts">
import { FormInfo, ChartResults } from "@/views/resourceAccess/components";
import { chartResults, formInfo } from "../components/interface";
import { reactive, ref } from "vue";
import { http } from "@/utils/http";
import dataMock_com from "./assets/dataMock_com.json";
import { socket } from "./socket";
import COM_BASIC_MOCK from "./assets/edgeCloud2/Qsparse_AlexNet_record.json";
import COM_OPT_MOCK from "./assets/edgeCloud2/FedLamp_AlexNet_record.json";
const formProps: formInfo = reactive({
  title: "模型压缩",
  btnNames: ["开始压缩", "暂停", "结束"],
  btnDisabled: [false, false, false],
  btnLoading: [false, false, false],
  formInfoList: [
    {
      id: 1,
      title: "模型选择",
      inputType: "0",
      options: [
        {
          value: JSON.stringify(["AlexNet", "CIFAR10"]),
          label: "AlexNet"
        },
        {
          value: JSON.stringify(["CNN", "EMNIST"]),
          label: "CNN"
        },
        {
          value: JSON.stringify(["VGG", "image100"]),
          label: "VGG16"
        }
      ]
    },
    {
      id: 2,
      title: "配置文件",
      inputType: "1",
      options: undefined
    },
    {
      id: 3,
      title: "基准训练方法",
      inputType: "0",
      options: [
        {
          value: "Qsparse",
          label: "Qsparse"
        },
        {
          value: "FedAvg",
          label: "FedAvg"
        }
      ]
    },
    {
      id: 4,
      title: "优化训练方法",
      inputType: "0",
      options: [
        {
          value: "FedLamp",
          label: "FedLamp"
        }
      ]
    }
  ]
});
const chartResultsProps: chartResults = reactive({
  headerNames: ["基准训练方法", "优化训练方法"],
  header: ["epoch1:  -1421.1546", "epoch1:  -82.1546"],
  result: "优化压缩方法比基准压缩方法降低模型大小40%，并提高模型精度10%",
  chartSelect: [1, 1],
  chartData: [
    {
      title: "模型大小（MB）",
      legend: [],
      yAxisData: ["未压缩", "基准压缩方法", "优化压缩方法"],
      seriesData: [5.5, 4.2, 4.8]
    },
    {
      title: "模型精度",
      legend: [],
      xAxisSetting: {
        max: 1
      },
      yAxisData: ["未压缩", "基准压缩方法", "优化压缩方法"],
      seriesData: [1.025, 0.88, 0.975]
    }
  ]
});

let mock = false;
let intervalReq = null;
let basicRes = null,
  optRes = null,
  originRes = null;
const receiveData = ref(false);
const sleep = (ms: number) => {
  return new Promise(resolve => setTimeout(resolve, ms));
};

const initStaticChart = (dataStatic1, dataStatic2) => {
  let seriesData0 = [],
    seriesData1 = [];

  const result1 = dataStatic1[dataStatic1.length - 1];
  const result2 = dataStatic2[dataStatic2.length - 1];
  seriesData0 = [
    result1.uncompressed_model_size,
    result1.compressed_model_size,
    result2.compressed_model_size
  ];
  seriesData1 = [result1.uncompressed_accuracy, result1.acc, result2.acc];
  const calculateSave = (val1: number, val2: number) =>
    (((val1 - val2) * 100) / val1).toFixed(2);

  const save_size = calculateSave(seriesData0[1], seriesData0[2]);
  const save_acc = calculateSave(seriesData1[2], seriesData1[1]);
  chartResultsProps.header[0] = `epoch${result1.epoch}: accuracy ${result1.acc}`;
  chartResultsProps.header[1] = `epoch${result2.epoch}: accuracy ${result2.acc}`;
  chartResultsProps.chartData[0].seriesData = seriesData0;
  chartResultsProps.chartData[1].seriesData = seriesData1;
  chartResultsProps.result = `优化压缩方法比基准压缩方法降低模型大小${save_size}%，并提高模型精度${save_acc}%`;
};
initStaticChart(COM_BASIC_MOCK, COM_OPT_MOCK);

const renderChart = (data: any, flag: number) => {
  if (flag == 2 || flag == 1) {
    chartResultsProps.header[flag - 1] =
      `epoch${data["epoch"]}: model size ${data["model_size"].toFixed(4)}, accuracy ${data["accuracy"].toFixed(4)}`;
  }
  chartResultsProps.chartData[0].seriesData[flag] = data["model_size"];
  chartResultsProps.chartData[1].seriesData[flag] = data["accuracy"];
};
const renderResult = () => {
  if (basicRes && optRes) {
    const bSize = basicRes.model_size,
      oSize = optRes.model_size;
    const bAcc = basicRes.accuracy,
      oAcc = optRes.accuracy;
    const calculateSave = (val1: number, val2: number) =>
      (((val1 - val2) * 100) / val1).toFixed(2);
    const saveSize = calculateSave(bSize, oSize),
      saveAcc = calculateSave(oAcc, bAcc);
    chartResultsProps.result = `优化压缩方法比基准压缩方法降低模型大小${saveSize}%，并提高模型精度${saveAcc}%`;
  }
};
const stopRender = () => {
  renderResult();
  clearInterval(intervalReq);
};
const stopSocket = () => {
  socket.off("model_compression_intermediate_result");
  socket.off("model_compression_end_train_confirm");
};
const initChartData = () => {
  chartResultsProps.header = ["准备中...", "准备中..."];
  chartResultsProps.chartData[0].seriesData = [];
  chartResultsProps.chartData[1].seriesData = [];
  chartResultsProps.result = "";
  receiveData.value = false;
};
// 开始时的按钮状态
const startBtnStatus1 = () => {
  formProps.btnDisabled[1] = true;
  formProps.btnDisabled[2] = true;
  formProps.btnLoading[0] = true;
  formProps.btnNames[0] = "压缩中...";
};
const startBtnStatus2 = () => {
  formProps.btnDisabled[2] = false;
};
// 终止时的按钮状态
const stopBtnStatus1 = () => {
  formProps.btnLoading = [false, false, true];
  formProps.btnDisabled = [true, true, false];
  formProps.btnNames[2] = "结束中...";
};
const stopBtnStatus2 = () => {
  formProps.btnLoading = [false, false, false];
  formProps.btnDisabled = [false, false, false];
  formProps.btnNames = ["开始压缩", "暂停", "结束"];
};
const btnClick1 = e => {
  initChartData();
  console.log(e);
  startBtnStatus1();
  /*后端data
    update_data = {
    'about': 'model_compression', 
    'is_optimal': 1, 
    'is_end': 0, 
    'model': 'FedAvg', 
    'epoch': 1, 
    'accuracy': 0.1, 
    'model_size': 1, 
    'uncompressed_model_size': 2
}
  } */
  if (mock) {
    // intervalReq = setTimeout(async () => {
    //   await http.request("get", "@/../public/dataMock_com.json").then(res => {
    //     if (res[0]["msg"] == "end") {
    //       console.log(res[0]);
    //       // initStaticChart(res[0]);
    //       stopRender();
    //       stopBtnStatus2();
    //     }
    //   });
    // }, 5000);
    setTimeout(() => {
      initStaticChart(COM_BASIC_MOCK, COM_OPT_MOCK);
      stopRender();
      stopBtnStatus2();
    }, 5000);
  } else {
    const task = JSON.parse(e[1][0].value);
    const params = {
      about: "model_compression",
      model_type: task[0],
      dataset_type: task[1],
      config: e[1][1].value,
      baseline: e[1][2].value,
      optimal: e[1][3].value
    };
    socket.on("model_compression_intermediate_result", data => {
      if (!receiveData.value) {
        startBtnStatus2();
        receiveData.value = true;
      }
      const epoch = data["epoch"].toString();
      if (data["is_optimal"] == 1) {
        optRes = {
          epoch: epoch,
          model_size: data["model_size"],
          accuracy: data["accuracy"]
        };
        renderChart(optRes, 2);
        console.log("optResCom", optRes.model_size, optRes.accuracy);
      } else {
        basicRes = {
          epoch: epoch,
          model_size: data["model_size"],
          accuracy: data["accuracy"]
        };
        renderChart(basicRes, 1);
        console.log("basicResCom", basicRes.model_size, basicRes.accuracy);

        originRes = {
          epoch: epoch,
          model_size: data["uncompressed_model_size"],
          accuracy: data["uncompressed_accuracy"]
        };
        renderChart(originRes, 0);
        console.log("originResCom", originRes.model_size, originRes.accuracy);
      }
      console.log(data);
    });
    socket.on("model_compression_end_train_confirm", data => {
      // 不存在暂停
      stopRender();
      stopSocket();
      stopBtnStatus2();
      console.log("model_compression_end_train_confirm1", data);
    });
    socket.emit("start_train", params, res => {
      console.log("model_compression_training_start", params);
    });
  }
};
const btnClick2 = e => {
  console.log(e);
  console.log(e, "btnClick22, Panel Father");
};
const btnClick3 = async e => {
  stopBtnStatus1();
  stopRender();
  socket.on("model_compression_end_train_confirm", data => {
    stopSocket();
    stopBtnStatus2();
    console.log("model_compression_end_train_confirm2", data);
  });
  if (!mock) {
    socket.emit(
      "end_train",
      {
        about: "model_compression",
        baseline: e[1][2].value,
        optimal: e[1][3].value
      },
      data => {
        console.log("end_train", data);
      }
    );
  }
  console.log(e, "btnClick33, Panel Father");
};
</script>

<template>
  <el-row :gutter="20">
    <el-col :span="12" style="min-height: 200px">
      <el-col style="min-height: 200px">
        <FormInfo
          :title="formProps.title"
          :btnNames="formProps.btnNames"
          :formInfoList="formProps.formInfoList"
          :btnDisabled="formProps.btnDisabled"
          :btnLoading="formProps.btnLoading"
          @btnClick1="btnClick1"
          @btnClick2="btnClick2"
          @btnClick3="btnClick3"
        />
      </el-col>
    </el-col>
    <el-col :span="12" style="min-height: 200px">
      <el-col style="min-height: 200px">
        <ChartResults
          :headerNames="chartResultsProps.headerNames"
          :header="chartResultsProps.header"
          :chartSelect="chartResultsProps.chartSelect"
          :chartData="chartResultsProps.chartData"
          :result="chartResultsProps.result"
        />
      </el-col>
    </el-col>
  </el-row>
</template>
